
// https://tech.meituan.com/2016/11/18/disruptor.html
public class FalseSharing {

    private static ValuePadding[] longs;
//    Thread num 1 duration = 288
//    Thread num 2 duration = 322
//    Thread num 3 duration = 306
//    Thread num 4 duration = 301
//    Thread num 5 duration = 313
//    Thread num 6 duration = 351
//    Thread num 7 duration = 529
//    Thread num 8 duration = 422
//    Thread num 9 duration = 503

//    private static ValueNoPadding[] longs;
//    Thread num 1 duration = 282
//    Thread num 2 duration = 1778
//    Thread num 3 duration = 1877
//    Thread num 4 duration = 2446
//    Thread num 5 duration = 3525
//    Thread num 6 duration = 3705
//    Thread num 7 duration = 3136
//    Thread num 8 duration = 3062
//    Thread num 9 duration = 2463

//    private static ValueContended[] longs;

    public static void main(final String[] args) throws Exception {

        for (int i = 1; i < 10; i++) {
            System.gc();
            final long start = System.currentTimeMillis();
            runTest(i);
            System.out.println("Thread num " + i + " duration = " + (System.currentTimeMillis() - start));
        }

    }

    private static void runTest(int NUM_THREADS) throws InterruptedException {
        Thread[] threads = new Thread[NUM_THREADS];
        longs = new ValuePadding[NUM_THREADS];
//        longs = new ValueNoPadding[NUM_THREADS];
//        longs = new ValueContended[NUM_THREADS];
        for (int i = 0; i < NUM_THREADS; i++)
//            longs[i] = new ValueContended();
//            longs[i] = new ValueNoPadding();
            longs[i] = new ValuePadding();

        for (int i = 0; i < NUM_THREADS; i++) {
            final int index = i;
            threads[i] = new Thread(() -> {
                long l = 500L * 1000L * 100L + 1L;
                while (0 != --l) {
                    longs[index].value = 0L;
//                    longs[index].value1 = 0L;
//                    longs[index].value2 = 0L;
//                    longs[index].value3 = 0L;
                }
            });
        }

        for (Thread t : threads) t.start();

        for (Thread t : threads) t.join();
    }

    public final static class ValuePadding {
        protected long p1, p2, p3, p4, p5, p6, p7;
        protected volatile long value = 0L;
        protected long p9, p10, p11, p12, p13, p14;
        protected long p15;
    }

    public final static class ValueNoPadding {
        // protected long p1, p2, p3, p4, p5, p6, p7;
        protected volatile long value = 0L;
        // protected long p9, p10, p11, p12, p13, p14, p15;
    }
}
